//#define BADCODE

using System;
using System.Threading;

public sealed class Program {
   public static void Main() {
      Int32[] denominators = { 1, 2, 3 };
      
      // Have another thread do the work
      ThreadPool.QueueUserWorkItem(Divide100By, denominators);

      // DEMO: Give Divide100By a chance to validate the array elements
      Thread.Sleep(50);	

      // Make an array element no longer valid for the Divide100By method
      denominators[2] = 0;

      Console.WriteLine("Press <Enter> when you see the results.");
      Console.ReadLine();
   }

   private static void Divide100By(Object o) {

#if BADCODE
      // This code demonstrates the problem
      Int32[] denominators = (Int32[]) o;
#else
      // This code fixes the problem by making a copy of the array
      // The copy is validated and used throughout the rest of the method
      Int32[] denominatorsInput = (Int32[]) o;
      Int32[] denominators = new Int32[denominatorsInput.Length];
      Array.Copy(denominatorsInput, denominators, denominators.Length);
#endif

      // Validate all the elements in the array argument
      for (Int32 index = 0; index < denominators.Length; index++) {
         if (denominators[index] == 0) 
            throw new ArgumentOutOfRangeException("denominators", 
               String.Format("Index {0} contains 0", index));
      }
      Console.WriteLine(
         "All denominators are valid; DivideByZeroException can't occur.");

      // DEMO: Give Main a chance to invalidate an array element
      Thread.Sleep(100);
      
      // All elements are valid, now do the work
      for (Int32 index = 0; index < denominators.Length; index++) {
         Console.WriteLine("100 / {0} = {1}", 
            denominators[index], 100 / denominators[index]);
      }
   }
}

internal sealed class SomeType {
	internal static Byte[] ReadFileBytes(String path) {
		System.IO.FileStream fs = null;
		try {
			fs = new System.IO.FileStream(path, System.IO.FileMode.Open);
			Byte[] data = new byte[fs.Length];
			fs.Read(data, 0, (Int32) fs.Length);
			return data;
		}
		catch (Exception) {
		}
      // TODO: Blah
      return null;
   }
}